package it.ap.sa.core.util;

import java.util.ArrayList;
import java.util.List;

import org.apache.commons.beanutils.BeanUtilsBean2;

/**
 * Converter Util
 */
public class PageBeanUtils {

	/**
	 * Crea una lista di oggetti del tipo popolandoli con la lista passati in
	 * ingresso
	 * 
	 * @param inputs
	 * @param classe
	 * @return
	 * @throws Exception
	 */
	public static <S, D> List<D> convertListDbToPage(List<S> inputs, Class<D> classe) throws Exception {
		return convertListDbToPage(inputs, classe, null);
	}

	public static <S, D> List<S> convertListPageToDb(List<D> inputs, Class<S> classe) throws Exception {
		return convertListPageToDb(inputs, classe, null);
	}

	public static <S, D> List<D> convertListDbToPage(List<S> inputs, Class<D> classe, IBeanPopulate<S, D> populate)
			throws Exception {
		if (inputs != null) {
			List<D> ret = new ArrayList<D>();
			for (S org : inputs) {
				D dest = (D) classe.newInstance();
				if (populate != null) {
					dest = populate.convertdbToPage(org);
				} else {
					BeanUtilsBean2.getInstance().getPropertyUtils().copyProperties(dest, org);
				}
				ret.add(dest);
			}
			return ret;
		} else {
			return null;
		}
	}

	public static <S, D> List<S> convertListPageToDb(List<D> inputs, Class<S> classe, IBeanPopulate<S, D> populate)
			throws Exception {
		if (inputs != null) {
			List<S> ret = new ArrayList<S>();
			for (D org : inputs) {
				S dest = (S) classe.newInstance();
				if (populate != null) {
					dest = populate.convertpageToDb(org);
				} else {
					BeanUtilsBean2.getInstance().getPropertyUtils().copyProperties(dest, org);
				}
				ret.add(dest);
			}
			return ret;
		} else {
			return null;
		}
	}
	
	public static <S, D, P> List<D> convertListDbToPage(List<S> inputs, Class<D> classe, Object param, IBeanParamPopulate<S, D, P> populate)
			throws Exception {
		if (inputs != null) {
			List<D> ret = new ArrayList<D>();
			for (S org : inputs) {
				D dest = (D) classe.newInstance();
				if (populate != null) {
					dest = populate.convertdbToPage(org, param);
				} else {
					BeanUtilsBean2.getInstance().getPropertyUtils().copyProperties(dest, org);
				}
				ret.add(dest);
			}
			return ret;
		} else {
			return null;
		}
	}

	public static <S, D, P> List<S> convertListPageToDb(List<D> inputs, Class<S> classe, Object param, IBeanParamPopulate<S, D, P> populate)
			throws Exception {
		if (inputs != null) {
			List<S> ret = new ArrayList<S>();
			for (D org : inputs) {
				S dest = (S) classe.newInstance();
				if (populate != null) {
					dest = populate.convertpageToDb(org, param);
				} else {
					BeanUtilsBean2.getInstance().getPropertyUtils().copyProperties(dest, org);
				}
				ret.add(dest);
			}
			return ret;
		} else {
			return null;
		}
	}

	public static <S, D> D convertDbToPage(S source, D dest, IBeanPopulate<S, D> populate) throws Exception {
		if (source != null) {

			BeanUtilsBean2.getInstance().getPropertyUtils().copyProperties(dest, source);
			if (populate != null) {
				dest = populate.convertdbToPage(source);
			}
			return dest;
		} else {
			return null;
		}
	}

	public static <S, D> S convertPageToDb(D source, S dest, IBeanPopulate<S, D> populate) throws Exception {
		if (source != null) {

			BeanUtilsBean2.getInstance().getPropertyUtils().copyProperties(dest, source);
			if (populate != null) {
				dest = populate.convertpageToDb(source);
			}
			return dest;
		} else {
			return null;
		}
	}

	/**
	 * Converte il bean S a D mediante il converter passato in ingresso. Se il
	 * converter è null ricopia solo le proprietà uguali
	 * 
	 * @param org
	 * @param classe
	 * @return
	 * @throws Exception
	 */
	public static <S, D> D convertDbToPage(S org, Class<D> classe) throws Exception {
		// compilation ambiguos bug return convertDbToPage(org, classe, null);

		if (org != null) {
			D dest = (D) classe.newInstance();

			BeanUtilsBean2.getInstance().getPropertyUtils().copyProperties(dest, org);

			return dest;
		} else {
			return null;
		}
	}

	public static <S, D> S convertPageToDb(D org, Class<S> classe) throws Exception {
		// compilation ambiguos return convertPageToDb(org, classe, null);
		if (org != null) {
			S dest = (S) classe.newInstance();

			BeanUtilsBean2.getInstance().getPropertyUtils().copyProperties(dest, org);

			return dest;
		} else {
			return null;
		}
	}

	/**
	 * Converte il bean S a D mediante il converter passato in ingresso. Se il
	 * converter è null ricopia solo le proprietà uguali
	 * 
	 * @param org
	 * @param classe
	 * @return
	 * @throws Exception
	 */
	public static <S, D> D convertDbToPage(S org, Class<D> classe, IBeanPopulate<S, D> converter) throws Exception {
		if (org != null) {
			D dest = (D) classe.newInstance();

			if (converter != null) {
				dest = converter.convertdbToPage(org);
			} else {
				BeanUtilsBean2.getInstance().getPropertyUtils().copyProperties(dest, org);
			}
			return dest;
		} else {
			return null;
		}
	}

	public static <S, D> S convertPageToDb(D org, Class<S> classe, IBeanPopulate<S, D> converter) throws Exception {
		if (org != null) {
			S dest = (S) classe.newInstance();

			if (converter != null) {
				dest = converter.convertpageToDb(org);
			} else {
				BeanUtilsBean2.getInstance().getPropertyUtils().copyProperties(dest, org);
			}
			return dest;
		} else {
			return null;
		}
	}
	
	/**
	 * Converte il bean S a D mediante il converter passato in ingresso. Se il
	 * converter è null ricopia solo le proprietà uguali
	 * 
	 * @param org
	 * @param classe
	 * @return
	 * @throws Exception
	 */
	public static <S, D, P> D convertDbToPage(S org, Class<D> classe, Object param, IBeanParamPopulate<S, D, P> converter) throws Exception {
		if (org != null) {
			D dest = (D) classe.newInstance();

			if (converter != null) {
				dest = converter.convertdbToPage(org, param);
			} else {
				BeanUtilsBean2.getInstance().getPropertyUtils().copyProperties(dest, org);
			}
			return dest;
		} else {
			return null;
		}
	}

	public static <S, D, P> S convertPageToDb(D org, Class<S> classe, Object param, IBeanParamPopulate<S, D, P> converter) throws Exception {
		if (org != null) {
			S dest = (S) classe.newInstance();

			if (converter != null) {
				dest = converter.convertpageToDb(org, param);
			} else {
				BeanUtilsBean2.getInstance().getPropertyUtils().copyProperties(dest, org);
			}
			return dest;
		} else {
			return null;
		}
	}

	/**
	 * 
	 * @param org
	 * @param classe
	 * @return
	 * @throws Exception
	 */
	public static <S, D> D convertCtrlToPage(S org, Class<D> classe, IJsonBeanPopulate<S, D> converter) throws Exception {
		if (org != null) {
			D dest = (D) classe.newInstance();

			BeanUtilsBean2.getInstance().getPropertyUtils().copyProperties(dest, org);
			if (converter != null) {
				dest = converter.convertctrlToPage(org);
			}
			return dest;
		} else {
			return null;
		}
	}

	public static <S, D> S convertPageToCtrl(D org, Class<S> classe, IJsonBeanPopulate<S, D> converter) throws Exception {
		if (org != null) {
			S dest = (S) classe.newInstance();

			BeanUtilsBean2.getInstance().getPropertyUtils().copyProperties(dest, org);
			if (converter != null) {
				dest = converter.convertpageToCtrl(org);
			}
			return dest;
		} else {
			return null;
		}
	}

}